/* 
 * File:   FormAnalyzer.cpp
 * Author: Henrique
 * 
 * Created on 26 de Outubro de 2011, 11:12
 */

#include "FormAnalyzer.h"

#include "ExtratorDeCamposSemMarcadores.h"
#include "PreProcessamentoComMarcadores.h"
#include "ExtratorDeInformacoesSemMarcadores.h"
#include "ComparadorGroundTruth.h"


//Getters e setters

ExtratorDeCampos* FormAnalyzer::getExtratorDeCoordenadas() const {
    return extratorDeCoordenadas;
}

void FormAnalyzer::setExtratorDeCoordenadas(ExtratorDeCampos* ext) {
    extratorDeCoordenadas = ext;
}

void FormAnalyzer::setPreprocess(PreProcessamento* preprocess) {
    this->preprocess = preprocess;
}

PreProcessamento* FormAnalyzer::getPreprocess() const {
    return preprocess;
}

void FormAnalyzer::setExtratorDeInformacoes(ExtratorDeInformacoes* extratorDeInformacoes) {
    this->extratorDeInformacoes = extratorDeInformacoes;
}

ExtratorDeInformacoes* FormAnalyzer::getExtratorDeInformacoes() const {
    return extratorDeInformacoes;
}

//Construtores/destrutores

FormAnalyzer::FormAnalyzer() {
    extratorDeCoordenadas = new ExtratorDeCamposSemMarcadores();
}

FormAnalyzer::FormAnalyzer(bool marcador) {
    if (marcador) {
        //extratorDeCoordenadas = new CoordExtractWithMarker();
        //preprocess = new PreProcessWithMarker;
    } else {
        extratorDeCoordenadas = new ExtratorDeCamposSemMarcadores();
        preprocess = new PreProcessamentoSemMarcadores;
        extratorDeInformacoes = new ExtratorDeInformacoesSemMarcadores();
    }
}

FormAnalyzer::~FormAnalyzer() {
}

string FormAnalyzer::compareAnswers(const char * archieveFileName, Conteudo* conteudo) {
    ifstream archieve(archieveFileName);

    string file = "Respostas.txt";
    Auxiliar::createArchieve(file, conteudo->toString());
    ifstream answer(file.c_str());

    int right = 0;
    int wrong = 0;

    char answerLine[200];
    char archieveLine[200];

    stringstream content;
    content << "";

    while (true) {
        if (answer.eof()) {
            break;
        }
        archieve.getline(archieveLine, 200);
        answer.getline(answerLine, 200);

        if (strcmp(answerLine, "") != 0) {
            content << "Imagem: " << answerLine << "\n";
        }

        while (strcmp(answerLine, "") != 0) {
            answer.getline(answerLine, 200);
            archieve.getline(archieveLine, 200);
            if (strcmp(answerLine, "") != 0) {
                if (strcmp(answerLine, archieveLine) == 0) {
                    right++;
                } else {
                    wrong++;
                    content << "      Resposta esperada: " << archieveLine
                            << "\n";
                    content << "      Resposta encontrada: " << answerLine
                            << "\n\n";
                }
            }
        }
        content << "\n";
    }
    archieve.close();
    answer.close();

    int total = right + wrong;
    double hitRate = 100 * ((double) right / (double) total);
    double errorRate = 100 * ((double) wrong / (double) total);

    content << "\nTotal de questões avaliadas: " << total << "\n";
    content << "   Questões corretas: " << right << "\n";
    content << "   Questões erradas: " << wrong << "\n \n \n";

    content << "Taxa de acerto: " << hitRate << "%\n";
    content << "Taxa de erro: " << errorRate << "%\n";

    return content.str();
}
    
int main(int argc, char **argv) {
    if (argc < 6) {
        cout << "Para que o programa execute corretaemente insira:" << endl;
        cout << "1 - Programa." << endl;
        cout << "2 - Arquivo com gabarito das marcações." << endl;
        cout << "3 - Número de imagens totais a serem analisadas." << endl;
        cout << "4 - Path para as imagens.(Ex.: /home/imagens/Gabarito...)"
                << endl;
        cout
                << "5 - Extensão em que se encontra a imagem. (Ex.: .png, .jpg, .bmp ... )"
                << endl;
        cout << "6 - Arquivo para comparar o GroundTruth"
                << endl;
    } else {
        FormAnalyzer* finder = new FormAnalyzer(false);

        string arquivoMarcacoes = argv[1];
        int totalDocuments = atof(argv[2]);
        string path = argv[3];
        string extension = argv[4];
        string arquivoGroundTruth = argv[5];
        string content;

        Conteudo* conteudo = new Conteudo();

        vector<string> imgs;
        for (int i = 1; i <= totalDocuments; i++) {
            imgs.push_back(Auxiliar::fileName(path, extension, i));
        }

        for (vector<string>::iterator it = imgs.begin(); it != imgs.end(); ++it) {
            string picture = *it;

            cout << picture << endl;

            IplImage * imagem = cvLoadImage(picture.c_str());

            pair<IplImage*, IplImage*> results = finder->getPreprocess()->preProcessar(imagem);
            IplImage* sum = results.first;
            IplImage* dst = results.second;

            Estrutura* estrutura = finder->getExtratorDeCoordenadas()->encontrarCampos(sum);

            content.append(picture);
            content.append(" ");
            content.append(finder->getExtratorDeInformacoes()->extrairInformacao(estrutura, dst));
            content.append("\n");

            cvReleaseImage(&imagem);
            cvReleaseImage(&dst);
            cvReleaseImage(&sum);

            conteudo->addInformacao(content);
            content = "";
        }

        string correcao;
        correcao.append(finder->compareAnswers(arquivoMarcacoes.c_str(), conteudo));

        ComparadorGroundTruth* comparador = new ComparadorGroundTruth();
        double acerto = comparador->verificarQualidade(arquivoGroundTruth.c_str(), conteudo);
        std::ostringstream s;
        s << "Ground Truth: " << acerto << endl;
        correcao.append(s.str());

        string newFile = "ComparacaoDasRespostas.txt";
        Auxiliar::createArchieve(newFile, correcao);
    }
}

